package com.ruoyi.common.redis.utils;

import cn.hutool.json.JSONUtil;
import com.ruoyi.common.core.constant.DynamicExportConstants;
import com.ruoyi.common.core.enums.DynamicExportDto;
import com.ruoyi.common.core.enums.DynamicExportTemplateTypeEnum;
import com.ruoyi.common.core.exception.CustomException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.redis.service.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author: Ssw
 * @CreateTime: 2022-12-12  15:51
 * @Description:
 */

@Component
public class DynamicExportUtil {

    @Autowired
    public RedisService redisService;


    /**
     * 获取json
     * @return
     */
    public String getTemplateJson(DynamicExportTemplateTypeEnum typeEnum){
        Long userId = SecurityUtils.getUserId();
        if(Objects.isNull(userId)){
            return getOriginJson(typeEnum.getCode());
        }
        //取出的json需要转换下
        return  getCache(userId,typeEnum.getCode());
    }

    /**
     * 从缓存中取
     * @param userId
     * @param type
     * @return
     */
    private String getCache(Long userId,Integer type){
        String cacheStr =redisService.getCacheStr(keyJoin(userId,type));
        if(StringUtils.isBlank(cacheStr)){
            return getOriginJson(type);
        }
        //取出的json需要转换下
        return  comparison((String) com.alibaba.fastjson.JSON.parse(cacheStr),type);
    }

    private static String getOriginJson(Integer code) {
        DynamicExportTemplateTypeEnum enumByType = DynamicExportTemplateTypeEnum.getEnumByCode(code);
        switch (enumByType){
            case REFUND:
                return DynamicExportConstants.REFUND_EXPORT_TEMPLATE;
            case REFUND_COST:
                return DynamicExportConstants.REFUND_COST_JSON_EXPORT_TEMPLATE;
            case GOODS:
                return DynamicExportConstants.GOODS_JSON_EXPORT_TEMPLATE;
            default:
                throw new CustomException("类型未找到");
        }
    }


    public static String comparison(String userJson,Integer type){

        List<DynamicExportDto> userDto = JSONUtil.toList(userJson, DynamicExportDto.class);
        List<DynamicExportDto> originDto = JSONUtil.toList(getOriginJson(type), DynamicExportDto.class);
        int userSize = userDto.size();
        boolean isChange=false;
        for (int i = 0; i < originDto.size(); i++) {
            DynamicExportDto exportDto = originDto.get(i);
            if(i<userSize){
                DynamicExportDto userEx = userDto.get(i);
                List<DynamicExportDto.Content> originContentList = exportDto.getList();
                List<DynamicExportDto.Content> userContentList = userEx.getList();
                //说明有差异
                if(originContentList.size()!=userContentList.size()){
                    isChange=true;
                    Map<String, DynamicExportDto.Content> map = userContentList.stream().collect(Collectors.toMap(DynamicExportDto.Content::getFieldTitle, e -> e));
                    originContentList.forEach(item -> {
                        DynamicExportDto.Content content = map.get(item.getFieldTitle());
                        if(Objects.nonNull(content)){
                            item.setChoose(content.getChoose());
                            item.setDisabled(content.getDisabled());
                            item.setTitle(content.getTitle());
                            item.setFieldTitle(content.getFieldTitle());
                        }
                    });
                }else{
                    Map<String, DynamicExportDto.Content> map = originContentList.stream().collect(Collectors.toMap(DynamicExportDto.Content::getFieldTitle, e -> e));
                    userContentList.forEach(item -> {
                        DynamicExportDto.Content content = map.get(item.getFieldTitle());
                        if(Objects.nonNull(content)){
                            item.setChoose(item.getChoose());
                            item.setDisabled(content.getDisabled());
                            item.setTitle(content.getTitle());
                            item.setFieldTitle(content.getFieldTitle());
                        }
                    });
                }
            }
        }
        //说明有差异
        if(originDto.size()!=userSize){
            isChange=true;
        }

        if(isChange){
            return JSONUtil.toJsonStr(originDto);
        }
        return JSONUtil.toJsonStr(userDto);
    }



    /**
     * 设置json
     * @param json
     */
    public void setJson(String json,DynamicExportTemplateTypeEnum typeEnum){
        Long userId = SecurityUtils.getUserId();
        if(Objects.nonNull(userId)){
            redisService.setCacheObject(keyJoin(userId,typeEnum.getCode()),json);
        }
    }
    private String keyJoin(Long id,Integer code){
        return DynamicExportConstants.REDIS_CONSTANT_EXPORT_TEMPLATE+code+id;
    }


    /*    public static void main(String[] args) {
        Class<SalesRefundExportDto> aClass = SalesRefundExportDto.class;
        Field[] fields = aClass.getDeclaredFields();
        List<Field> fields1 = Arrays.asList(fields);
        List<ExportDto.Content> collect = fields1.stream().map(e -> {

            ExcelProperty annotation = e.getDeclaredAnnotation(ExcelProperty.class);
            if (Objects.nonNull(annotation)) {
                String name = e.getName();
                String[] annotationName = annotation.value();
                ExportDto.Content content = new ExportDto.Content();
                content.setTitle(annotationName[0]);
                content.setFieldTitle(name);
                content.setDisabled(false);
                content.setChoose(true);
                return content;

            }
            return null;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        String jsonStr = JSONUtil.toJsonStr(collect);
        System.out.println(jsonStr);
    }*/
}
